//-------------------------------------------------------------------
//	Copyright (c) 2012-2014 Zhirnov Andrey
//	This file is part of the "UXGEN-ES" project.
//	See copyright notice in "Engine.h".
//-------------------------------------------------------------------

#pragma once

// Platforms //
#include "Audio/Bass/BassEngine.h"
#include "Audio/OpenSLES/SLESEngine.h"

namespace Engine
{
namespace Audio
{

	class AudioSample;
	SHARED_POINTER( AudioSample );



	//
	// Audio Sample
	//

	class AudioSample : public BaseAudioSample
	{
	// types
	public:
		//
		// Audio Load Parameters
		//
		struct AudioLoadParams : ResLoadParams
		{
		// variables
		public:

		// methods
		public:
			AudioLoadParams () : ResLoadParams( Signature() )
			{}

			static signature_t Signature ()
			{
				return CompileTime::TSignature8< 'A', 'S', 'A', 'M', 'P', 'L' >::value;
			}
		};

		typedef void (* OnFinishedCallback_t) (AudioSample *, void *parameter);


	// variables
	protected:
		OnFinishedCallback_t	_callback;
		void *					_callbackParam;


	// methods
	public:
		AudioSample (const EngineSubSystemsRef ess);
		~AudioSample ();

		void  SetCallback (OnFinishedCallback_t onFinished, void *param);

		void  StartPlaying ();

		bool  IsPlaying ();


		// Resource //
		virtual bool IsLoadedWithParams (const ResLoadParams &params) const override;


		static AudioSamplePtr	New (const EngineSubSystemsRef ess);

		static AudioLoadParams	GetDefaultLoadParams ();


	protected:
		virtual void _OnFinished () override;
		
		virtual void  _Destroy () override;
	};


	
/*
=================================================
	constructor
=================================================
*/
	inline AudioSample::AudioSample (const EngineSubSystemsRef ess) :
		BaseAudioSample( ess ),		_callback(null),	_callbackParam(null)
	{
	}
	
/*
=================================================
	destructor
=================================================
*/
	inline AudioSample::~AudioSample ()
	{
		_Destroy();
	}
	
/*
=================================================
	_Destroy
=================================================
*/
	inline void AudioSample::_Destroy ()
	{
		BaseAudioSample::_Destroy();

		_callback		= null;
		_callbackParam	= null;
	}
	
/*
=================================================
	StartPlaying
----
	start playing from begining of sound sample
=================================================
*/
	inline void AudioSample::StartPlaying ()
	{
		//SetPositionMillisec( 0 );
		Stop();
		Play();
	}
	
/*
=================================================
	IsPlaying
=================================================
*/
	inline bool AudioSample::IsPlaying ()
	{
		return not IsLooping() and GetState() != EPlayingState::PLAY;
	}

/*
=================================================
	SetCallback
=================================================
*/
	inline void AudioSample::SetCallback (OnFinishedCallback_t onFinished, void *param)
	{
		_callback		= onFinished;
		_callbackParam	= param;
	}
	
/*
=================================================
	_OnFinished
=================================================
*/
	inline void AudioSample::_OnFinished ()
	{
		if ( _callback != null )
		{
			_callback( this, _callbackParam );
		}
	}
		
/*
=================================================
	IsLoadedWithParams
=================================================
*/
	inline bool AudioSample::IsLoadedWithParams (const ResLoadParams &params) const
	{
		return true;
	}
	
/*
=================================================
	GetDefaultLoadParams
=================================================
*/
	inline AudioSample::AudioLoadParams  AudioSample::GetDefaultLoadParams ()
	{
		return AudioLoadParams();
	}
	
/*
=================================================
	New
=================================================
*/
	inline AudioSamplePtr  AudioSample::New (const EngineSubSystemsRef ess)
	{
		return BaseObject::_New( new AudioSample( ess ) );
	}


}	// Audio
}	// Engine
